"use client";

import { ReactNode, createContext, useRef, useState } from "react";
import {
  KeyInfo,
  LightConfig,
  LightEffectConfig,
  MouseMacro,
  MacroProfile,
  MouseConfig,
  MouseConfigInfo,
  FilterDevice,
  DPIGroup,
  DpiConfig,
} from "../types/types";
import { DeviceComm, connectDeviceHID } from "../devices/MouseDevice";
import Keys from "@/src/config/keys.json";
import { useTranslation } from "../i18n";
import { getKeyInfoName } from "../libs/keycode";
import {
  DpiColorConfig,
  KeyLayout,
  MouseKey,
  MouseProfile,
} from "../types/types.v1.d";
import useProfile from "../hooks/useProfile";
import useMacro from "../hooks/useMacro";
import { MainProps } from "./type";
import {
  DpiProtocolControl,
  dpiValues,
} from "../components/Mouse/DPISetting/dpiProtocolUsage";
import { convertToDPIGroups } from "../utils/colorUtils";
import { APP_CONFIGS } from "../config/appConfig";

export const MainContext = createContext({} as MainProps);

function MainProvider({ children }: { children: ReactNode }) {
  // 设备连接状态
  const [deviceStatus, setDeviceStatus] = useState(false);
  // 设备是否在线
  const [deviceOnline, setDeviceOnline] = useState(false);

  // 设备名称
  const [deviceName, setDeviceName] = useState("");
  // 设备ID
  const [deviceId, setDeviceId] = useState("");
  // 设备版本
  const [deviceVersion, setDeviceVersion] = useState("1.0.1");
  // 接收器版本
  const [dongleVersion, setDongleVersion] = useState("1.0.1");
  //
  const [currentTab, setCurrentTab] = useState("home");

  // 当前选中的配置文件
  const [profileIndex, setProfileIndex] = useState(0);

  // 键盘布局
  const [mouseLayout, setMouseLayout] = useState<KeyLayout[]>([]);
  const [mouseKeys, setMouseKeys] = useState<MouseKey[]>([]);
  const [selKeyIndex, setSelKeyIndex] = useState(-1);
  const [macroProfiles, setMacroProfiles] = useState<MacroProfile[]>([]);
  const [currentSelectMacroProfile, setCurrentSelectMacroProfile] = useState(0);

  const [connectedMouse, setConnectedMouse] = useState<DeviceComm>();
  const [editMode, setEditMode] = useState("");
  const [mouseConfig, setMouseConfig] = useState<MouseConfig>();
  const [mouseConfigInfo, setMouseConfigInfo] = useState<MouseConfigInfo>();
  const [lightEffectConfig, setLightEffectConfig] = useState<
    LightEffectConfig[]
  >([]);
  const [lightConfig, setLightConfig] = useState<LightConfig>();
  const [mouseDPIInfo, setMouseDPIInfo] = useState<DpiConfig>({
    min: 200,
    max: 12000,
    defaultCount: 6,
    defaultSelected: 2,
    sliderMarks: [200, 400, 600, 800, 1000, 12000],
  } as DpiConfig);
  const [mouseDPIGroups, setMouseDPIGroups] = useState<DPIGroup[]>([]);
  const [dpiSyncData, setDpiSyncData] = useState(true); // 同步数据状态
  const [hasMacroType4, setHasMacroType4] = useState(false);

  const [macroList, setMacroList] = useState<MouseMacro[]>([]);
  const [keyInfos, setKeyInfos] = useState<KeyInfo[]>([]);

  const [mouseDpi, setMouseDpi] = useState<number>(0);
  const [mouseReportRate, setMouseReportRate] = useState<number>(0);
  const [battery, setBattery] = useState<number>(0);
  const [chargeFlag, setChargeFlag] = useState<number>(0);
  const [mouseStatus, setMouseStatus] = useState<number>(0);
  const [mouseProfile, setMouseProfile] = useState<MouseProfile>();
  const [connectMode, setConnectMode] = useState("USB");
  const [matchMode, setMatchMode] = useState(false);
  const [dpiInit, setDpiInit] = useState(false);
  // 添加DPI协议相关状态
  const [dpiColors, setDpiColors] = useState<DpiColorConfig | undefined>(
    undefined
  );
  const [dpiProtocolControl, setDpiProtocolControl] = useState<
    DpiProtocolControl | undefined
  >(undefined);

  const { t } = useTranslation("common");
  // 添加防止重复刷新的标志
  const isRefreshingDpiRef = useRef(false);

  const profile = useProfile();
  const macro = useMacro();

  // 连接设备
  const connectMouse = async (
    filter: FilterDevice[] | undefined,
    deviceName: string = ""
  ) => {
    // 连接设备
    const connectedMouse = await connectDeviceHID(filter, deviceName);
    if (connectedMouse === undefined) {
      console.log("connectedMouse undefined, not find device!");
      return false;
    }

    // 设置设备连接状态
    setDeviceStatus(true);
    setConnectedMouse(connectedMouse);

    // 异步执行获取鼠标数据
    await initDefaultConfig(connectedMouse);
    // 初始化所有鼠标数据
    await initAllMouseData(connectedMouse);

    connectedMouse.onListeners.push({
      name: "statu",
      fb: (value: any) => {
        setMouseDpi(value.dpi);
        setMouseReportRate(value.reportRate);
      },
    });

    connectedMouse.onListeners.push({
      name: "profile",
      fb: (value: any) => {
        console.log("profileIndex", value.profile);
        setProfileIndex(value.profile);
      },
    });

    connectedMouse.onListeners.push({
      name: "battery",
      fb: (value: any) => {
        setBattery(value.battery);
        setChargeFlag(value.charge_flag);
      },
    });

    connectedMouse.onListeners.push({
      name: "mouse_status",
      fb: (value: any) => {
        console.log("mouse_status", value);
        setMouseStatus(value.mouse_status);
      },
    });

    connectedMouse.onListeners.push({
      name: "openApp",
      fb: (value: any) => {
        console.log("openApp", value.openApp);
        const appConfig = APP_CONFIGS.find(
          (app) => app.index === value.openApp
        );

        if (appConfig) {
          window.location.href = appConfig.protocol;
        }
      },
    });

    connectedMouse.onListeners.push({
      name: "match",
      fb: (value: any) => {
        //console.log(value);
      },
    });

    return true;
  };

  //todo 异步加载自定义配置文件
  const loadCustomProfile = async (profile: MouseProfile) => {
    if (!profile) {
      return;
    }

    setMouseConfigInfo(profile.defaultConfig);
    setMouseKeys(profile.mouseKeys);
    setDpiSyncData(true);
    if (connectedMouse) {
      connectedMouse.setMouseKeys(profile.mouseKeys, profileIndex);
      connectedMouse?.setMouseConfigData(profile.defaultConfig, profileIndex);
    }
  };

  // 设备断开
  const disconnectMouse = () => {
    // 设置设备连接状态
    setDeviceStatus(false);
    setConnectedMouse(undefined);
  };

  const initDefaultConfig = async (connectedMouse: DeviceComm) => {
    const config = await connectedMouse.loadDefaultConfig();

    setMouseLayout(config.keysLayout);
    setMouseConfig(config);
    setMouseKeys(config.keys);
    setMouseDPIInfo(config.dpiConfig);
    // setMouseDPIGroups(config.dpi);

    const dpiProtocolControl = new DpiProtocolControl(connectedMouse, {
      onDpiColorsChange: (colors: DpiColorConfig) => {
        setDpiColors(colors);

        if (colors && colors.colors) {
          const dpiGroups = convertToDPIGroups(colors.colors[0], dpiValues);

          setMouseDPIGroups(dpiGroups);
        }
      },
    });
    setDpiProtocolControl(dpiProtocolControl);

    try {
      let currentColors: DpiColorConfig;

      try {
        currentColors = await connectedMouse.getDpiColors();
        console.log("currentColors", currentColors);

        const isValidColors =
          currentColors &&
          currentColors.colors &&
          currentColors.colors.length === 2;

        if (!isValidColors) {
          console.log("使用默认颜色初始化");
          await dpiProtocolControl.configureDpiColors();
          currentColors = await connectedMouse.getDpiColors();
        }
      } catch (error) {
        console.log("使用默认配置初始化:", error);
      }

      setDpiColors(currentColors);

      if (currentColors && currentColors.colors) {
        const dpiGroups = convertToDPIGroups(
          currentColors.colors[0],
          dpiValues
        );
        setMouseDPIGroups(dpiGroups);
      }
    } catch (error) {
      console.error("G80设备DPI协议初始化失败:", error);
    }
  };

  const getDefaultKeycode = () => {
    const keys = Keys.system.list.flatMap((customKey) => {
      return customKey.keycodes.map((key: any) => {
        return key.lang ? { ...key, name: t(key.lang) } : key;
      });
    });
    return keys;
  };

  const compareVersions = (version1: string, version2: string): number => {
    const v1 = version1.split(".").map(Number);
    const v2 = version2.split(".").map(Number);

    for (let i = 0; i < v1.length; i++) {
      if (v1[i] < v2[i]) return -1;
      if (v1[i] > v2[i]) return 1;
    }

    return 0;
  };

  const initAllMouseData = async (connectedMouse: DeviceComm) => {
    let macroProfiles_: MacroProfile[];
    const data = localStorage.getItem("mouse_macro");
    if (data) {
      macroProfiles_ = JSON.parse(data);
      setMacroProfiles(macroProfiles_);
    }

    let deviceId = connectedMouse.api.getHID().productName;
    setDeviceId(deviceId);
    //todo 初始化鼠标配置， id为硬件标识 配置数据结构 MouseProfile
    profile.initProfiles(deviceId);
    let macroList = macro.initMacro(deviceId);

    // 设置设备名称
    setDeviceName(connectedMouse.api.getHID().productName);

    // 获取连接模式
    const connected_mode = await connectedMouse.getConnectMode();
    setConnectMode(connected_mode);

    // 获取版本信息
    const version_info = await connectedMouse.getVersionInfo();
    // console.log("version_info", version_info);
    setDeviceVersion(version_info.version);
    setDongleVersion(version_info.version);
    // if (connected_mode == "有线连接") {
    //   setDeviceVersion(version_info.version);
    // } else {
    //   setDongleVersion(version_info.version);
    // }

    // 获取电量信息
    const battery_info = await connectedMouse.getBatteryInfo();
    //console.log("battery_info", battery_info);
    if (battery_info && battery_info.battery_value > 0) {
      setBattery(battery_info.battery_value);
      setChargeFlag(battery_info.charge_flag);
    }
    // console.log("version_info.version", version_info.version);

    if (compareVersions(version_info.version, "2.0.0") < 0) {
      setHasMacroType4(false);
    } else {
      setHasMacroType4(true);
    }
    // 获取鼠标按键配置信息
    const config = await connectedMouse.loadDefaultConfig();
    const keyInfos: MouseKey[] = await connectedMouse.getMouseKeys();
    if (keyInfos) {
      const keycodeInfos = getDefaultKeycode();
      // console.log("keycodeInfos", keycodeInfos);

      // 使用 map 来生成新的键位配置
      const newKeyInfos = config.keys.map((keyinfo, index) => {
        const new_keyinfo = keyInfos[index];
        // 若读取数组不足或该索引不存在，则保持默认
        if (!new_keyinfo) return keyinfo;
        // 如果新键位信息存在并且 type 为 0 或 0xff，保持原始键位信息
        if (new_keyinfo.type === 0 || new_keyinfo.type === 0xff) return keyinfo;

        let key_name = getKeyInfoName(
          keycodeInfos,
          new_keyinfo.type,
          new_keyinfo.code1,
          new_keyinfo.code2,
          new_keyinfo.code3,
          t
        );
        // console.log("key_name", key_name, "new_keyinfo", new_keyinfo);

        if (new_keyinfo.type == 0x70 && macroList && macroList.length > 0) {
          if (new_keyinfo.code1 < macroList.length) {
            key_name = macroList[new_keyinfo.code1].name;
          }
        }

        return {
          ...keyinfo,
          keyName: key_name,
          type: new_keyinfo.type,
          code1: new_keyinfo.code1,
          code2: new_keyinfo.code2,
          code3: new_keyinfo.code3,
        };
      });
      // console.log("newKeyInfos", newKeyInfos);
      // map 完成后，调用 setMouseKeys 更新状态
      setMouseKeys(newKeyInfos);
      profile.updateMouseKeys(newKeyInfos);
    }

    // 获取配置信息
    const mouseconfig_info = await connectedMouse.getMouseConfigInfo();
    //console.log("mouseconfig_info:", mouseconfig_info);
    if (
      mouseconfig_info &&
      mouseconfig_info.dpi1_value > 0 &&
      mouseconfig_info.dpi1_value < 65000
    ) {
      setDpiSyncData(true);
      setMouseDpi(mouseconfig_info.dpi_index);
      setMouseReportRate(mouseconfig_info.report_rate);
      setMouseConfigInfo(mouseconfig_info);
      profile.updateMouseConfig(profileIndex, mouseconfig_info);
      //console.log("MainProvider", mouseconfig_info);
    }

    // 获取板载配置
    const boardConfig = await connectedMouse.getBoardConfig();
    console.log("boardConfig", boardConfig);
    setProfileIndex(boardConfig.currentProfileIndex);
  };

  // 重置单键
  const resetSingleKey = async (connectedMouse: DeviceComm, index: number) => {
    const config = await connectedMouse.loadDefaultConfig();
    const newKey = {
      ...mouseKeys[index],
      keyName: config.keys[index].keyName,
      type: config.keys[index].type,
      code1: config.keys[index].code1,
      code2: config.keys[index].code2,
      code3: config.keys[index].code3,
    };

    const updatedMouseKeys = mouseKeys.map((key) =>
      key.index === index ? newKey : key
    );
    setMouseKeys(updatedMouseKeys);
    profile.updateMouseKeys(updatedMouseKeys);
    if (connectedMouse) {
      connectedMouse.setMouseKeys(updatedMouseKeys, profileIndex);
    }
  };

  // 重置所有按键
  const resetAllMouseKeys = async (connectedMouse: DeviceComm) => {
    const config = await connectedMouse.loadDefaultConfig();
    console.log("resetAllMouseKeys", config.keys);
    setMouseKeys(config.keys);
    profile.updateMouseKeys(profileIndex, config.keys);
    await connectedMouse?.resetAllMouseKeys();
  };

  // 恢复出厂设置
  const restoreFactorySettings = async (connectedMouse: DeviceComm) => {
    const config = await connectedMouse.loadDefaultConfig();

    await initDefaultConfig(connectedMouse);

    // 设置鼠标配置
    const mouseconfig_ = {
      profile_index: config.config.profile_index,
      report_rate: config.config.report_rate,
      dpi_index: config.config.dpi_index,
      dpi_flag: config.config.dpi_count,
      dpi_count: config.config.dpi_count,
      dpi1_value: config.config.dpi1_value,
      dpi2_value: config.config.dpi2_value,
      dpi3_value: config.config.dpi3_value,
      dpi4_value: config.config.dpi4_value,
      dpi5_value: config.config.dpi5_value,
      dpi6_value: config.config.dpi6_value,
      scroll_flag: config.config.scroll_flag,
      lod_value: config.config.lod_value,
      sensor_flag: config.config.sensor_flag,
      key_respond: config.config.key_respond,
      sleep_light: config.config.sleep_light,
      highspeed_mode: config.config.highspeed_mode,
      wakeup_flag: config.config.wakeup_flag,
      move_light_flag: config.config.move_light_flag,
      light_mode: config.config.light_mode,
    } as MouseConfigInfo;
    setDpiSyncData(true);
    setMouseConfigInfo(mouseconfig_);
    profile.updateMouseConfig(profileIndex, mouseconfig_);
    await connectedMouse?.setMouseConfigData(mouseconfig_);
    await dpiProtocolControl.configureDpiColors();

    setMouseKeys(config.keys);
    profile.updateMouseKeys(profileIndex, config.keys);
    await connectedMouse?.resetAllMouseKeys();
  };

  const updateDpiColors = async (newColors: DpiColorConfig) => {
    if (!connectedMouse) {
      console.warn("设备未连接");
      return;
    }

    try {
      // 先发送颜色配置到设备
      await connectedMouse.setDpiColors(newColors);
      await new Promise((resolve) => setTimeout(resolve, 100));

      // 然后从设备读取最新颜色配置以确保一致性
      const currentColors = await connectedMouse.getDpiColors();
      setDpiColors(currentColors);
      const {
        dpi1_value,
        dpi2_value,
        dpi3_value,
        dpi4_value,
        dpi5_value,
        dpi6_value,
      } = mouseConfigInfo;

      // 同时刷新DPI组
      if (currentColors && currentColors.colors) {
        const dpiGroups = convertToDPIGroups(currentColors.colors[0], [
          dpi1_value,
          dpi2_value,
          dpi3_value,
          dpi4_value,
          dpi5_value,
          dpi6_value,
        ]);
        console.log("dpiGroups", dpiGroups);
        setMouseDPIGroups(dpiGroups);
      }
    } catch (error) {
      console.error("更新DPI颜色配置失败:", error);
    }
  };

  const mainProps: MainProps = {
    deviceStatus,
    setDeviceStatus,
    deviceOnline,
    setDeviceOnline,
    deviceName,
    setDeviceName,
    deviceId,
    setDeviceId,
    deviceVersion,
    setDeviceVersion,
    dongleVersion,
    setDongleVersion,
    currentTab,
    setCurrentTab,
    selKeyIndex,
    setSelKeyIndex,
    macroProfiles,
    setMacroProfiles,
    currentSelectMacroProfile,
    setCurrentSelectMacroProfile,
    connectedMouse,
    editMode,
    setEditMode,
    connectMouse,
    mouseKeys,
    setMouseKeys,
    mouseConfig,
    lightEffectConfig,
    setLightEffectConfig,
    lightConfig,
    setLightConfig,
    mouseDPIInfo,
    setMouseDPIInfo,
    mouseDPIGroups,
    setMouseDPIGroups,
    // 添加DPI协议相关状态
    dpiColors,
    setDpiColors,
    dpiProtocolControl,
    setDpiProtocolControl,
    dpiSyncData,
    setDpiSyncData,
    macroList,
    keyInfos,
    setKeyInfos,
    mouseLayout,
    setMouseLayout,
    disconnectMouse,
    mouseDpi,
    setMouseDpi,
    mouseReportRate,
    setMouseReportRate,
    mouseConfigInfo,
    setMouseConfigInfo,
    battery,
    chargeFlag,
    mouseStatus,
    t,
    mouseProfile,
    setMouseProfile,
    connectMode,
    matchMode,
    setMatchMode,
    initAllMouseData,
    resetSingleKey,
    resetAllMouseKeys,
    restoreFactorySettings,
    dpiInit,
    setDpiInit,
    profileIndex,
    setProfileIndex,
    hasMacroType4,
    setHasMacroType4,
    compareVersions,
    profile,
    macro,
    loadCustomProfile,
    // 添加DPI协议方法
    updateDpiColors,
    setDongleInfo: () => {},
  };

  return (
    <MainContext.Provider value={mainProps}>{children}</MainContext.Provider>
  );
}

export default MainProvider;
